home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / UNITRE11.ARJ / UNITREE.DOC next >
Text File  |  1992-06-24  |  9KB  |  227 lines

  1. UNITREE -- display the UNIT dependency TREE from a Turbo Pascal compilation.
  2. Version 1.1.
  3.  
  4. Copyright (C) 1992 J. C. Rice.  All Rights Reserved.
  5.  
  6. Individuals and business corporations may use UNITREE free of charge.  You
  7. may neither sell it nor charge for distributing it without express consent of
  8. the copyright holder.
  9.  
  10. rice@zizania.cray.com
  11.  
  12.               ---------------------------------------------------
  13.  
  14. *** How to use it ***
  15.  
  16.    TPC /B [other options] main.pas | UNITREE > report.fil
  17. or TPC /B [other options] main.pas | UNITREE | viewer.exe
  18.  
  19. where:
  20.  
  21.    other options are whatever else you need to compile your program
  22.    main.pas      is the name of your main program
  23.    report.fil    is the file you want the dependency tree written to
  24.    viewer.exe    is the name of your favorite display program (LIST, LESS,
  25.                  etc.)
  26.  
  27. If you don't redirect the output of UNITREE, you'll see it on the screen.
  28. There are no command line parameters or options.  TPCX can be substituted for
  29. TPC.  You can redirect the output of TPC to a file and later redirect it as
  30. input to unitree.
  31.  
  32.               ---------------------------------------------------
  33.  
  34. *** Why to use it ***
  35.  
  36. I'm not going to explain UNITs and USES in this brief file.  If you aren't
  37. already familiar with them, read chapter 3 of Borland's TP User's Guide --
  38. but if you aren't already familiar with them, odds are you don't need
  39. unitree.
  40.  
  41. Unitree displays the *compilation-ordered* dependency tree of units.  It does
  42. not display the complete graph of all interdependencies; rather, it shows how
  43. the TP compiler finds and resolves the USES statements, and in what order.
  44.  
  45. To see what that means, consider the following trivial example, consisting
  46. of a main program and four units:
  47.  
  48. program main;   unit math;     unit stats;    unit ext_prec;  unit prob_lib;
  49. uses            uses           uses           {uses none}     {uses none}
  50.   stats,          ext_prec;      prob_lib,
  51.   math;                          math;
  52.  
  53. Here's what Turbo Pascal does in response to a full build of main.pas:
  54.  
  55.          step                       .PAS files open
  56.  
  57.   1. Open main.pas                  main
  58.   2. Note the "uses stats"          main
  59.   3. Open stats.pas                 main stats
  60.   4. Note the "uses prob_lib"       main stats
  61.   5. Open prob_lib.pas              main stats prob_lib
  62.   6. Compile prob_lib.pas           main stats prob_lib
  63.   7. Close prob_lib.pas             main stats
  64.   8. Return to stats.pas            main stats
  65.   9. Note the "uses math"           main stats
  66.  10. Open math.pas                  main stats math
  67.  11. Note the "uses ext_prec"       main stats math
  68.  12. Open ext_prec.pas              main stats math ext_prec
  69.  13. Compile ext_prec.pas           main stats math ext_prec
  70.  14. Close ext_prec.pas             main stats math
  71.  15. Return to math.pas             main stats math
  72.  16. Compile math.pas               main stats math
  73.  17. Close math.pas                 main stats
  74.  18. Return to stats.pas            main stats
  75.  19. Compile stats.pas              main stats
  76.  20. Close stats.pas                main
  77.  21. Return to main.pas             main
  78.  22. Note the "uses math" refers
  79.      to an already-compiled unit    main
  80.  23. Compile main.pas               main
  81.  24. Close main.pas
  82.  
  83. And here is the output of unitree for this compilation:
  84.  
  85. MAIN
  86. └─STATS (4)
  87.   ├─PROB_LIB (1)
  88.   └─MATH (3)
  89.     └─EXT_PREC (2)
  90.  
  91. (Ignore the parenthetical numbers for now).  As you can see, at one point in
  92. the compilation there were four modules in some intermediate stage of
  93. compilation.  Now look what happens if we make a single change: switch the
  94. order of the units in the main program's USES statement:
  95.  
  96. program main;   unit math;     unit stats;    unit ext_prec;  unit prob_lib;
  97. uses            uses           uses
  98.   math, {***}     ext_prec;      prob_lib,
  99.   stats;{***}                    math;
  100.  
  101.      step (some omitted    .PAS files open
  102.      for brevity)
  103.  
  104.   1. Open main.pas          main
  105.   2. Open math.pas          main math
  106.   3. Open ext_prec.pas      main math ext_prec
  107.   4. Close ext_prec.pas     main math
  108.   5. Close math.pas         main
  109.   6. Open stats.pas         main stats
  110.   7. Open prob_lib.pas      main stats prob_lib
  111.   8. Close prob_lib.pas     main stats
  112.   9. math already compiled  main stats
  113.  10. Close stats.pas        main
  114.  11. Close main.pas
  115.  
  116. Here is the output of unitree for this compilation:
  117.  
  118. MAIN
  119. ├─MATH (2)
  120. │ └─EXT_PREC (1)
  121. └─STATS (4)
  122.   └─PROB_LIB (3)
  123.  
  124. Now the maximum "compilation depth" is three modules, rather than four.
  125. While this is obvious on inspection of these five trivial modules, imagine a
  126. project of 50+ units, each of which might use a dozen units -- not so easy to
  127. make the necessary mental picture any more.  And definitely not easy to make
  128. this further refinement, as shown by the trivial example again:
  129.  
  130. program main;   unit math;     unit stats;    unit ext_prec;  unit prob_lib;
  131. uses            uses           uses
  132.   ext_prec,{***}  ext_prec;      prob_lib,
  133.   prob_lib,{***}                 math;
  134.   math,
  135.   stats;
  136.  
  137. Here is the output of unitree for this compilation:
  138.  
  139. MAIN
  140. ├─EXT_PREC (1)
  141. ├─PROB_LIB (2)
  142. ├─MATH (3)
  143. └─STATS (4)
  144.  
  145. By including units (ext_prec, prob_lib) in the main program that are *not*
  146. directly used, the compilation depth shrinks to two.
  147.  
  148. Why the fuss over compilation depth?  Because the compilation depth of a
  149. large project may cause TP to exceed MS-DOS's limit on the number of open
  150. files.  The result is compile-time error 13, "too many open files."  The
  151. Borland manuals diagnose this as an insufficient FILES= setting in
  152. CONFIG.SYS, but it's more likely to result from USES statements that aren't
  153. ordered to best advantage.
  154.  
  155. Your strategy, then, is to move "leaf" units -- those that don't rely on any
  156. others -- to the beginning of the main program's USES statement.  Then use
  157. the output of unitree to find other units that depend just on leaves, and
  158. place those next, etc.  [Remember to leave the Borland overlay unit and the
  159. unit with your ovrinit call *before* anything that's overlaid.]  You can also
  160. use unitree to look for the highest compilation depth (the units farthest to
  161. the right on the output) and try to shorten that path.
  162.  
  163. There's another interesting consequence to the order in which Turbo Pascal
  164. resolves compilation dependencies: it determines the order in which unit
  165. intializtion code will be executed.  Observe the unitree output for the three
  166. examples, along with the runtime output of the program:
  167.  
  168.     graph                     execution
  169.  
  170. First example:
  171.  
  172. MAIN                      initializing prob_lib
  173. └─STATS (4)               initializing ext_prec
  174.   ├─PROB_LIB (1)          initializing math
  175.   └─MATH (3)              initializing stats
  176.     └─EXT_PREC (2)        executing main
  177.  
  178.  
  179. Second example:
  180.  
  181. MAIN                      initializing ext_prec
  182. ├─MATH (2)                initializing math
  183. │ └─EXT_PREC (1)          initializing prob_lib
  184. └─STATS (4)               initializing stats
  185.   └─PROB_LIB (3)          executing main
  186.  
  187.  
  188. Third example:
  189.  
  190. MAIN                      initializing ext_prec
  191. ├─EXT_PREC (1)            initializing prob_lib
  192. ├─PROB_LIB (2)            initializing math
  193. ├─MATH (3)                initializing stats
  194. └─STATS (4)               executing main
  195.  
  196.  
  197. You can see that the initialization code is placed into sequence at the time 
  198. each unit's compilation is finally resolved.  In the first example, for 
  199. instance, prob_lib is the first unit to be completely compiled, and its
  200. initialization code runs first.  The numbers in parentheses, shown after the
  201. unit names, indicate the order in which initialization code will be executed.
  202.  
  203. A final note: be sure to use the /B (build all) command line option on
  204. TPC/TPCX, to get the full tree.  If you use /M (make as needed) you'll still
  205. get the output, but there's no telling what pieces of the picture might be
  206. omitted.
  207.  
  208.               ---------------------------------------------------
  209.  
  210. *** History ***
  211.  
  212. This little program is the result of a conversation I had with the
  213. ever-reliable Duncan Murdoch, about compilation error 13.  I appreciate his
  214. advice.
  215.  
  216. 92-06 Version 1.0.  Represents nearly 70 minutes of development time, and
  217.                     almost 10 whole minutes of testing.  Seems to work with
  218.                     TP versions 5.5 and 6.0; no idea about earlier versions.
  219. 92-06 Version 1.1.  Fixed boneheaded error too embarassing to describe.
  220.                     Minor symptom: program does not run.
  221.  
  222. If you use this program, consider dropping me a note to say that it was
  223. helpful or that it wasn't (and why).  I'd appreciate it.  The address is:
  224.  
  225.         internet:   rice@zizania.cray.com
  226.         uucp:       [backbone]!uunet!cray!rice
  227.